home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / game / think / WBTRIS_1_54.lha / WBTRIS_1.54 / Source / WBTRIS.c < prev    next >
C/C++ Source or Header  |  1993-05-06  |  69KB  |  1,980 lines

  1. /*
  2.    *******************************************************************************
  3.    *                                                                             *
  4.    *                                                                             *
  5.    *     WW            WW  BBBBBBBB  TTTTTTTTTT  RRRRRRRR   II     SSSSSSS       *
  6.    *     WW            WW  BB     BB     TT      RR     RR  II    SS     SS      *
  7.    *      WW    WW    WW   BB     BB     TT      RR     RR  II    SS             *
  8.    *      WW   WWWW   WW   BBBBBBB       TT      RR   RRR   II     SSSSSSS       *
  9.    *       WW WW  WW WW    BB    BB      TT      RRRRRR     II           SS      *
  10.    *       WWWW    WWWW    BB     BB     TT      RR   RR    II           SS      *
  11.    *        WWW    WWW     BB     BB     TT      RR    RR   II    SS     SS      *
  12.    *        WW      WW     BBBBBBBB      TT      RR     RR  II     SSSSSSS       *
  13.    *                                                                             *
  14.    *                                                                             *
  15.    *          COPYRIGHT © 1993 by Dirk Böhmer  ( medusa@uni-paderborn.de )       *
  16.    *                                                                             *
  17.    *                            & Ralf Pieper                                    *
  18.    *                                                                             *
  19.    *          All rights reserved.                                               *
  20.    *                                                                             *
  21.    *                                                                             *
  22.    *******************************************************************************
  23. */
  24.  
  25. #include "WBTRIS.h"
  26.  
  27. #define SHOWHISCORE TRUE
  28. #define SAVEHISCORE FALSE
  29. #define RIGHTFIELD TRUE
  30. #define LEFTFIELD FALSE
  31.  
  32. /*#define TEMPLATE "LEFT=LEFTEDGE/N/K,TOP=TOPEDGE/N/K,N=NAME/K,NOLOCK=NOLOCKNAME/K/S\
  33. ,NONEXT=SHOWNONEXT/K/S,NOLACE/K/S,LEVEL/N/K\
  34. ,PULLDOWNTICKS/N/K\
  35. ,R=MOVERIGHT/K,L=MOVELEFT/K,RR=ROTATERIGHT/K,RL=ROTATELEFT/K\
  36. ,D=MOVEDOWN/K,DQ=MOVEDOWNQUICK/K,TP=TWOPLAYER/K/S" */
  37.  
  38. #define TEMPLATE "LEFT=LEFTEDGE/N/K,TOP=TOPEDGE/N/K,N=NAME/K,NOLOCK=NOLOCKNAME/K/S\
  39. ,NONEXT=SHOWNONEXT/K/S,NOLACE/K/S,LEVEL/N/K\
  40. ,PULLDOWNTICKS/N/K\
  41. ,R=MOVERIGHT/K,L=MOVELEFT/K,RR=ROTATERIGHT/K,RL=ROTATELEFT/K\
  42. ,D=MOVEDOWN/K,DQ=MOVEDOWNQUICK/K,TF=TILEFILE/K"
  43.  
  44.  
  45. extern struct Image Pausebrush;
  46. extern struct Image logo;
  47.  
  48. extern struct Image Gruen;
  49. extern struct Image GruenWeiss;
  50. extern struct Image GruenWeissSchach;
  51. extern struct Image GruenWeissSchraeg;
  52. extern struct Image Schwarz;
  53. extern struct Image SchwarzGruen;
  54. extern struct Image SchwarzWeiss;
  55.  
  56. extern struct Image GruenNI;
  57. extern struct Image GruenWeissNI;
  58. extern struct Image GruenWeissSchachNI;
  59. extern struct Image GruenWeissSchraegNI;
  60. extern struct Image SchwarzNI;
  61. extern struct Image SchwarzGruenNI;
  62. extern struct Image SchwarzWeissNI;
  63.  
  64. char versionstring[] = "\0$VER: " PROG_NAME VERSION " " "von " AUTHOR;
  65.  
  66. UBYTE *CYCLELabels[] = {
  67.     (UBYTE *)"Pause",
  68.     (UBYTE *)"Go on",
  69.     NULL };
  70. ;
  71.  
  72. struct obj {
  73.   BOOL objData[4][4];
  74.   int color;
  75. };
  76.  
  77. struct obj objects[8];
  78. struct obj objects2[8];
  79.  
  80. int field[YSIZE+1][XSIZE+2] = {
  81.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  82.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  83.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  84.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  85.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  86.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  87.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  88.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  89.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  90.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  91.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  92.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  93.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  94.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  95.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  96.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  97.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  98.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  99.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  100.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  101.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  102.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  103.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  104.                         {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
  105.                      };
  106.  
  107. int field2[YSIZE+1][XSIZE+2] = {
  108.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  109.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  110.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  111.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  112.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  113.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  114.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  115.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  116.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  117.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  118.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  119.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  120.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  121.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  122.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  123.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  124.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  125.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  126.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  127.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  128.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  129.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  130.                         {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1},
  131.                         {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
  132.                      };
  133.  
  134. int            FieldsSpace = 125;
  135. short          YOffSet = YOFFSET;
  136. short          LGXOS;
  137. short          BOXXSIZE;
  138. short          BOXYSIZE;
  139. short          NEXTXOFFSET;
  140. short          MAINXOFFSET;
  141. BOOL           UseLace = TRUE;
  142. BOOL           TwoPlayer = FALSE;
  143. short          boxxsize;
  144. short          boxysize;
  145. int            Highscore;
  146. int            Score = 0;
  147. int            Lines = 0;
  148. int            time = DEFAULTTICKS;
  149. int            oldtime = DEFAULTTICKS;
  150. int            x = XSIZE/2;
  151. int            y = 0;
  152. int            time2 = DEFAULTTICKS;
  153. int            oldtime2 = DEFAULTTICKS;
  154. int            x2 = XSIZE/2;
  155. int            y2 = 0;
  156. UWORD          CursorUp    = CURSOR_UP,    CursorUp2    = CURSOR_UP2;
  157. UWORD          CursorDown  = CURSOR_DOWN,  CursorDown2  = CURSOR_DOWN2;
  158. UWORD          CursorLeft  = CURSOR_LEFT,  CursorLeft2  = CURSOR_LEFT2;
  159. UWORD          CursorRight = CURSOR_RIGHT, CursorRight2 = CURSOR_RIGHT2;
  160. UWORD          NormalSpace = SPACE   ,     NormalSpace2 = SPACE2;
  161. UWORD          QuickSpace  = QUICKSPACE,   QuickSpace2  = QUICKSPACE2;
  162.  
  163. /* Timer */
  164. BYTE                 TimerError = 0 ,  TimerError2 = 0 ;
  165. struct MsgPort      *TimerMP = NULL , *TimerMP2 = NULL ;
  166. struct timerequest  *TimerIO = NULL , *TimerIO2 = NULL ;
  167. struct Message      *TimerMSG = NULL, *TimerMSG2 = NULL;
  168.  
  169. /* Options */
  170. char        Name[25];
  171. BOOL        SpacePressed = FALSE, SpacePressed2 = FALSE;
  172. BOOL        lockname = TRUE;
  173. BOOL        nextteil = TRUE;
  174. int         LevelOffset = 0;
  175. int         pulldownticks = 0;
  176. int         WBTRIS_Window_Top = MAINWINDOWTOP;
  177. int         WBTRIS_Window_Left= MAINWINDOWLEFT;
  178.  
  179. struct RastPort   *rp = NULL;
  180. struct Library    *IntuitionBase = NULL;
  181. struct Library    *KeymapBase    = NULL;
  182. struct Library    *IconBase      = NULL;
  183. struct Window     *window        = NULL;
  184. struct obj        *objptr        = NULL;
  185. struct obj        *nextptr       = NULL;
  186. struct obj        *objptr2       = NULL;
  187. struct obj        *nextptr2      = NULL;
  188. struct Screen     *myscreen      = NULL;
  189. struct TextFont   *font = NULL, *font2 = NULL;
  190.  
  191. int LineCounter = 0;
  192. int Level;
  193.  
  194. struct TextAttr helvetica13 = {"helvetica.font", 13, 0, 0};
  195. struct TextAttr topaz8 = {"topaz.font", 8, 0, 0};
  196.  
  197. APTR           VisualInfo = NULL;
  198. struct Gadget *TetrisGList = NULL;
  199. struct Gadget *TetrisGadgets[9];
  200. BOOL           vonoptions = TRUE;
  201. char           TileFile[80];
  202.  
  203. int obj1 = 0;
  204. int obj2 = 0;
  205. int obj3 = 0;
  206. int obj4 = 0;
  207. int obj5 = 0;
  208. int obj6 = 0;
  209. int obj7 = 0;
  210.  
  211.  
  212.  
  213.  
  214. int wbmain(struct WBStartup *wbs)
  215. {
  216.    struct DiskObject *dobj = NULL;
  217.    char             **toolsarray;
  218.    char              *s = NULL;
  219.    char              *tail = NULL;
  220.  
  221.    strcpy(TileFile, "");
  222.  
  223.    if ((IconBase = OpenLibrary("icon.library", 37l)) == NULL)
  224.       exit(FALSE);
  225.  
  226.    CurrentDir(wbs->sm_ArgList->wa_Lock);
  227.    if (dobj = (struct DiskObject *) GetDiskObject(wbs->sm_ArgList->wa_Name)) {
  228.       toolsarray = (char **) dobj->do_ToolTypes;
  229.  
  230.       if (s = (char *) FindToolType(toolsarray, "LEFTEDGE"))
  231.          WBTRIS_Window_Left = atoi(s);
  232.       if (s = (char *) FindToolType(toolsarray, "TOPEDGE"))
  233.          WBTRIS_Window_Top = atoi(s);
  234.       if (s = (char *) FindToolType(toolsarray, "NAME"))
  235.          strcpy(Name, s);
  236.       if (s = (char *) FindToolType(toolsarray, "LOCKNAME")) {
  237.          if ((strcmp(s, "TRUE")) == NULL)
  238.             lockname = TRUE;
  239.          else
  240.             lockname = FALSE;
  241.       }
  242.       if (s = (char *) FindToolType(toolsarray, "SHOWNEXT")) {
  243.          if ((strcmp(s, "TRUE")) == NULL)
  244.             nextteil = TRUE;
  245.          else
  246.             nextteil = FALSE;
  247.       }
  248.       if (s = (char *) FindToolType(toolsarray, "USELACE")) {
  249.          if ((strcmp(s, "TRUE")) == NULL)
  250.             UseLace = TRUE;
  251.          else
  252.             UseLace = FALSE;
  253.       }
  254. /*      if (s = (char *) FindToolType(toolsarray, "TWOPLAYER")) {
  255.          if ((strcmp(s, "TRUE")) == NULL)
  256.             TwoPlayer = TRUE;
  257.          else
  258.             TwoPlayer = FALSE;
  259.       }
  260. */
  261.       if (s = (char *) FindToolType(toolsarray, "LEVEL"))
  262.          LevelOffset = atoi(s);
  263.       if (s = (char *) FindToolType(toolsarray, "PULLDOWNSPEED"))
  264.          pulldownticks = (20 - atoi(s))/2;
  265.  
  266.       if (s = (char *) FindToolType(toolsarray, "MOVERIGHT"))
  267.          CursorRight = strtol(s, &tail, 0);
  268.       if (s = (char *) FindToolType(toolsarray, "MOVELEFT"))
  269.          CursorLeft  = strtol(s, &tail, 0);
  270.       if (s = (char *) FindToolType(toolsarray, "ROTATERIGHT"))
  271.          CursorUp    = strtol(s, &tail, 0);
  272.       if (s = (char *) FindToolType(toolsarray, "ROTATELEFT"))
  273.          CursorDown  = strtol(s, &tail, 0);
  274.       if (s = (char *) FindToolType(toolsarray, "MOVEDOWN"))
  275.          NormalSpace = strtol(s, &tail, 0);
  276.       if (s = (char *) FindToolType(toolsarray, "MOVEDOWNQUICK"))
  277.          QuickSpace  = strtol(s, &tail, 0);
  278.       if (s = (char *) FindToolType(toolsarray, "TILEFILE"))
  279.          strcpy(TileFile, s);
  280.  
  281.       FreeDiskObject(dobj);
  282.    }
  283.  
  284.    if (IconBase)
  285.       CloseLibrary(IconBase);
  286.    Real_Main();
  287.    return(0);
  288. }
  289.  
  290.  
  291.  
  292. int main(void)
  293. {
  294.    int            i;
  295. /*   long           options[15];*/
  296.    long           options[15];
  297.    struct RDArgs *args = NULL;
  298.  
  299.    for (i=0; i<15; i++)
  300.       options[i] = 0L;
  301.  
  302. /*   for (i=0; i<15; i++)
  303.       options[i] = 0L;
  304. */
  305.  
  306.    strcpy(TileFile, "");
  307.  
  308.    args = ReadArgs(TEMPLATE, options, NULL);
  309.  
  310.    if (args) {
  311.       if (options[0])
  312.          WBTRIS_Window_Left = *(int *) options[0];
  313.       if (options[1])
  314.          WBTRIS_Window_Top = *(int *) options[1];
  315.       if (options[2])
  316.          strcpy(Name, (char *) options[2]);
  317.       if (options[3])
  318.          lockname = !options[3];
  319.       if (options[4])
  320.          nextteil = options[4];
  321.       if (options[5])
  322.          UseLace = !options[5];
  323.       if (options[6])
  324.          LevelOffset = *(int *) options[6];
  325.       if (options[7])
  326.          pulldownticks = (20 - *(int *) options[7])/2;
  327.       if (options[8])
  328.          CursorRight = (UWORD) strtol((char *) options[8], NULL, 0);
  329.       if (options[9])
  330.          CursorLeft = (UWORD) strtol((char *) options[9], NULL, 0);
  331.       if (options[10])
  332.          CursorUp = (UWORD) strtol((char *) options[10], NULL, 0);
  333.       if (options[11])
  334.          CursorDown = (UWORD) strtol((char *) options[11], NULL, 0);
  335.       if (options[12])
  336.          NormalSpace = (UWORD) strtol((char *) options[12], NULL, 0);
  337.       if (options[13])
  338.          QuickSpace = (UWORD) strtol((char *) options[13], NULL, 0);
  339.       if (options[14])
  340.          strcpy(TileFile, (char *) options[14]);
  341. /*      if (options[14])
  342.          TwoPlayer = options[14];*/
  343.    }
  344.    if (args)
  345.       FreeArgs(args);
  346.  
  347.    Real_Main();
  348.    return(0);
  349. }
  350.  
  351.  
  352.  
  353. int Real_Main(void)
  354. {
  355.    struct IntuiMessage *imsg = NULL;
  356.    struct InputEvent    inputevent = {0};
  357.    struct Gadget       *gad = NULL;
  358.    LONG                 windowsignal, timersignal, timersignal2;
  359.    BOOL                 Done = FALSE;
  360.    APTR                *eventptr = NULL;
  361.    long                 mask;
  362.    struct I0ExtSer     *reply = NULL;
  363.    WORD                 Width, Height;
  364.    char                 WindowTitle[80];
  365.    struct EasyStruct AskQuit = {
  366.        sizeof(struct EasyStruct),
  367.        0,
  368.        "Quit",
  369.        "Do you really want to quit?",
  370.        "Yes|Oops!",
  371.    };
  372.  
  373.    InitObjects();
  374.    openall();                    /* open Fonts, Libraries, VisualInfo, etc*/
  375.  
  376.    /* build windowtitle */
  377.    strcpy(WindowTitle, PROG_NAME);
  378.    strcat(WindowTitle, VERSION);
  379.  
  380.    if (UseLace) {
  381.       LGXOS = 5;
  382.       boxxsize = BOXXSIZE = 18;
  383.       boxysize = BOXYSIZE = 16;
  384.       NEXTXOFFSET = 14;
  385.       MAINXOFFSET = 122;
  386.    } else {
  387.       LGXOS = 15;
  388.       boxxsize = BOXXSIZE = 16;
  389.       boxysize = BOXYSIZE = 8;
  390.       NEXTXOFFSET = 155;
  391.       MAINXOFFSET = 252;
  392.    }
  393.  
  394.    YOffSet = YOFFSET + myscreen->WBorTop + (myscreen->Font->ta_YSize + 1);
  395.    if (TwoPlayer) {
  396.       Width = 2*(XSIZE*boxxsize) + 30 + MAINXOFFSET + FieldsSpace;
  397.       Height = YSIZE*boxysize + 11 + YOffSet;
  398.    } else {
  399.       Width = XSIZE*boxxsize + 35 + MAINXOFFSET;
  400.       Height = YSIZE*boxysize + 11 + YOffSet;
  401.    }
  402.  
  403.    gad = CreateAllGadgets(myscreen);
  404.  
  405.    window = OpenWindowTags(NULL,
  406.                             WA_Left,    WBTRIS_Window_Left,
  407.                             WA_Top,     WBTRIS_Window_Top,
  408.                             WA_Width,   Width,
  409.                             WA_Height,  Height,
  410.                             WA_ScreenTitle, "WBTRIS",
  411.                             WA_Title,   WindowTitle,
  412.                             WA_Flags,   WFLG_CLOSEGADGET | WFLG_ACTIVATE | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_RMBTRAP,
  413.                             WA_Gadgets, TetrisGList,
  414.                             WA_IDCMP,   BUTTONIDCMP | NUMBERIDCMP | IDCMP_REFRESHWINDOW | IDCMP_RAWKEY | IDCMP_CLOSEWINDOW
  415.                                       | WFLG_DEPTHGADGET | WFLG_SMART_REFRESH  | IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW,
  416.                             TAG_DONE);
  417.  
  418.    if (window == NULL)
  419.       closeout("Can't open window",RETURN_FAIL);
  420.  
  421.    rp = window->RPort;
  422.    Level = LevelOffset;
  423.  
  424.    x = XSIZE/2 - 1;
  425.    oldtime = time = DEFAULTTICKS - Level*2;
  426.    nextptr = RandomObject(LEFTFIELD);
  427.    objptr = RandomObject(LEFTFIELD);
  428.    y = 0;
  429.    if (InFirstLine(objptr) == TRUE)
  430.       y = 1;
  431.    if (nextteil == TRUE)
  432.       Draw_NextObject(nextptr, LEFTFIELD);
  433.  
  434.    if (TwoPlayer) {
  435.       x2 = XSIZE/2 - 1;
  436.       oldtime2 = time2 = DEFAULTTICKS - Level*2;
  437.       nextptr2 = RandomObject(RIGHTFIELD);
  438.       objptr2 = RandomObject(RIGHTFIELD);
  439.       y2 = 0;
  440.       if (InFirstLine(objptr2) == TRUE)
  441.          y2 = 1;
  442.       if (nextteil == TRUE)
  443.          Draw_NextObject(nextptr2, RIGHTFIELD);
  444.    }
  445.  
  446.    GT_RefreshWindow( window, NULL );
  447.  
  448.    DrawWindow();
  449.  
  450.  
  451.    timersignal  = 1L << TimerMP->mp_SigBit;
  452.    windowsignal = 1L << window->UserPort->mp_SigBit;
  453.  
  454.    /* Initialize InputEvent structure (already cleared to 0) */
  455.    inputevent.ie_Class = IECLASS_RAWKEY;
  456.  
  457.    Highscore = Loadhiscore();
  458.  
  459.    GT_SetGadgetAttrs(TetrisGadgets[GD_HighscoreGadget], window, NULL,
  460.                           GTNM_Number, (ULONG)Highscore,
  461.                           TAG_END);
  462.    GT_SetGadgetAttrs(TetrisGadgets[GD_LevelGadget], window, NULL,
  463.                           GTNM_Number, (ULONG)Level, TAG_END);
  464.  
  465.    TimerIO->tr_node.io_Command = TR_ADDREQUEST;
  466.    TimerIO->tr_time.tv_secs = 0;
  467.    TimerIO->tr_time.tv_micro = time * 20000;
  468.    SendIO((struct IORequest *) TimerIO);
  469.  
  470.    if (TwoPlayer) {
  471.       timersignal2  = 1L << TimerMP2->mp_SigBit;
  472.       TimerIO2->tr_node.io_Command = TR_ADDREQUEST;
  473.       TimerIO2->tr_time.tv_secs = 0;
  474.       TimerIO2->tr_time.tv_micro = time2 * 20000;
  475.       SendIO((struct IORequest *) TimerIO2);
  476.    }
  477.  
  478.    while(!Done) {
  479.       if (TwoPlayer)
  480.          mask = Wait(timersignal | timersignal2 | windowsignal);
  481.       else
  482.          mask = Wait(timersignal | windowsignal);
  483.  
  484.       /*
  485.       ** Signal kommt vom Timer
  486.       */
  487.       if (mask & timersignal) {
  488.          while(reply = (struct I0ExtSer *)GetMsg(TimerMP))
  489.          {
  490.             /* we don't need these messages */
  491.          }
  492.          AbortIO((struct IORequest *) TimerIO);
  493.          WaitIO((struct IORequest *) TimerIO);
  494.          TimerIO->tr_node.io_Command = TR_ADDREQUEST;
  495.          TimerIO->tr_time.tv_secs = 0;
  496.          TimerIO->tr_time.tv_micro = time * 20000;
  497.          SendIO((struct IORequest *) TimerIO);
  498.          if (CollisionDown(objptr, field, x, y, LEFTFIELD) == FALSE) {
  499.             AbortIO((struct IORequest *) TimerIO);
  500.             WaitIO((struct IORequest *) TimerIO);
  501.             time = oldtime;
  502.             Done = GameOver(field, lockname);
  503.             if (Done == FALSE) {
  504.                objptr = nextptr;
  505.                nextptr = RandomObject(LEFTFIELD);
  506.                y = 0 ;
  507.                if (InFirstLine(objptr) == TRUE)
  508.                   y = 1;
  509.  
  510.                x = XSIZE/2 - 1;
  511.                ClearNextField(LEFTFIELD);
  512.                if (nextteil == TRUE)
  513.                   Draw_NextObject(nextptr, LEFTFIELD);
  514.             }
  515.          } else {
  516.             Draw_Object(x, y, objptr, FALSE, LEFTFIELD);
  517.             y = y + 1;
  518.             Draw_Object(x, y, objptr, TRUE, LEFTFIELD);
  519.          }
  520.       }
  521.  
  522.       /*
  523.       ** Signal kommt vom Timer2
  524.       */
  525.       if ((mask & timersignal2) && TwoPlayer) {
  526.          while(reply = (struct I0ExtSer *)GetMsg(TimerMP2))
  527.          {
  528.             /* we don't need these messages */
  529.          }
  530.          AbortIO((struct IORequest *) TimerIO2);
  531.          WaitIO((struct IORequest *) TimerIO2);
  532.          TimerIO2->tr_node.io_Command = TR_ADDREQUEST;
  533.          TimerIO2->tr_time.tv_secs = 0;
  534.          TimerIO2->tr_time.tv_micro = time2 * 20000;
  535.          SendIO((struct IORequest *) TimerIO2);
  536.          if (CollisionDown(objptr2, field2, x2, y2, RIGHTFIELD) == FALSE) {
  537.             AbortIO((struct IORequest *) TimerIO2);
  538.             WaitIO((struct IORequest *) TimerIO2);
  539.             time2 = oldtime2;
  540.             Done = GameOver(field2, lockname);
  541.             if (Done == FALSE) {
  542.                objptr2 = nextptr2;
  543.                nextptr2 = RandomObject(RIGHTFIELD);
  544.                y2 = 0 ;
  545.                if (InFirstLine(objptr2) == TRUE)
  546.                   y2 = 1;
  547.  
  548.                x2 = XSIZE/2 - 1;
  549.                ClearNextField(RIGHTFIELD);
  550.                if (nextteil == TRUE)
  551.                   Draw_NextObject(nextptr2, RIGHTFIELD);
  552.             }
  553.          } else {
  554.             Draw_Object(x2, y2, objptr2, FALSE, RIGHTFIELD);
  555.             y2 = y2 + 1;
  556.             Draw_Object(x2, y2, objptr2, TRUE, RIGHTFIELD);
  557.          }
  558.       }
  559.  
  560.       /*
  561.       ** Signal kommt von Gadgets, Fenster, Tasten, usw.
  562.       */
  563.       if (mask & windowsignal) {
  564.          while (imsg = (struct IntuiMessage *)GetMsg(window->UserPort)) {
  565.             switch(imsg->Class) {
  566.                case IDCMP_GADGETUP:
  567.                   gad = (struct Gadget *)imsg->IAddress;
  568.                   switch(gad->GadgetID) {
  569.                      case GD_PauseGadget:
  570.                         Done = Pause();
  571.                         break;
  572.  
  573.                      case GD_NewGadget:
  574.                         NewGame(field, FALSE, FALSE);
  575.                         break;
  576.  
  577.                      case GD_ShowScoreGadget:
  578.                         HideField();
  579.                         HiscoreList(Name, Level, Score, LineCounter, window->LeftEdge, window->TopEdge, SHOWHISCORE);
  580.                         ReDrawField(field, LEFTFIELD);
  581.                         ReDrawField(field2, RIGHTFIELD);
  582.                         ClearAllMsgPorts();
  583.                         break;
  584.  
  585.                      case GD_OptGadget:
  586.                         OpenOptions(window->LeftEdge, window->TopEdge);
  587.                         NewGame(field, FALSE, TRUE);
  588.                         break;
  589.  
  590.                      case GD_StatGadget:
  591.                         HideField();
  592.                         statistic(window->LeftEdge, window->TopEdge, obj1, obj2, obj3, obj4, obj5, obj6, obj7);
  593.                         ReDrawField(field, LEFTFIELD);
  594.                         ReDrawField(field2, RIGHTFIELD);
  595.                         ClearAllMsgPorts();
  596.                         break;
  597.                   }
  598.                   break;
  599.  
  600.                   case IDCMP_REFRESHWINDOW:
  601.                      /* This handling is REQUIRED with GadTools. */
  602.                      GT_BeginRefresh(window);
  603.                      GT_EndRefresh(window, TRUE);
  604.                      break;
  605.  
  606.                   case IDCMP_INACTIVEWINDOW:
  607.                      WaitForActivateWindow();
  608.                      break;
  609.  
  610.                   case IDCMP_CLOSEWINDOW:
  611.                      QuitGame();
  612.                      break;
  613.  
  614.                   case IDCMP_RAWKEY:
  615.                      inputevent.ie_Code = imsg->Code;
  616.                      inputevent.ie_Qualifier = imsg->Qualifier;
  617.  
  618.  
  619.  
  620.                      if (imsg->Code == '\x45') {
  621.                         if (EasyRequest(NULL, &AskQuit, NULL, NULL))
  622.                            Done = TRUE;
  623.                         break;
  624.                      }
  625.                      if (imsg->Code == CursorUp) {
  626.                         if (Rotate_Matrixl(objptr, field, x, y, LEFTFIELD)) {
  627.                            Rotate_Matrixr(objptr, field, x, y, LEFTFIELD);
  628.                            Draw_Object(x, y, objptr, FALSE, LEFTFIELD);
  629.                            Rotate_Matrixl(objptr, field, x, y, LEFTFIELD);
  630.                            Draw_Object(x, y, objptr, TRUE, LEFTFIELD);
  631.                         }
  632.                      } else {
  633.                         if (imsg->Code == CursorDown) {
  634.                         if (Rotate_Matrixr(objptr, field, x, y, LEFTFIELD)) {
  635.                            Rotate_Matrixl(objptr, field, x, y, LEFTFIELD);
  636.                            Draw_Object(x, y, objptr, FALSE, LEFTFIELD);
  637.                            Rotate_Matrixr(objptr, field, x, y, LEFTFIELD);
  638.                            Draw_Object(x, y, objptr, TRUE, LEFTFIELD);
  639.                         }
  640.                      } else {
  641.                      if (imsg->Code == CursorLeft) {
  642.                         if (CollisionLeft(objptr, field, x, y) == TRUE) {
  643.                            Draw_Object(x, y, objptr, FALSE, LEFTFIELD);
  644.                            x = x-1;
  645.                            Draw_Object(x, y, objptr, TRUE, LEFTFIELD);
  646.                         }
  647.                      } else {
  648.                      if (imsg->Code == CursorRight) {
  649.                         if (CollisionRight(objptr, field, x, y) == TRUE) {
  650.                            Draw_Object(x, y, objptr, FALSE, LEFTFIELD);
  651.                            x=x+1;
  652.                            Draw_Object(x, y, objptr, TRUE, LEFTFIELD);
  653.                         }
  654.                      } else {
  655.                      if (imsg->Code == NormalSpace) {
  656.                         if (!SpacePressed) {
  657.                            AbortIO((struct IORequest *) TimerIO);
  658.                            WaitIO((struct IORequest *) TimerIO);
  659.                            SpacePressed = TRUE;
  660.                            oldtime = time;
  661.                            time = pulldownticks;
  662.                         }
  663.                      } else {
  664.                      if (imsg->Code == QuickSpace) {
  665.                         AbortIO((struct IORequest *) TimerIO);
  666.                         WaitIO((struct IORequest *) TimerIO);
  667.                         oldtime = time;
  668.                         time = 0;
  669.                      } else
  670.                      if (TwoPlayer) {
  671.                         if (imsg->Code == CursorUp2) {
  672.                            if (Rotate_Matrixl(objptr2, field2, x2, y2, RIGHTFIELD)) {
  673.                               Rotate_Matrixr(objptr2, field2, x2, y2, RIGHTFIELD);
  674.                               Draw_Object(x2, y2, objptr2, FALSE, RIGHTFIELD);
  675.                               Rotate_Matrixl(objptr2, field2, x2, y2, RIGHTFIELD);
  676.                               Draw_Object(x2, y2, objptr2, TRUE, RIGHTFIELD);
  677.                            }
  678.                         } else {
  679.                         if (imsg->Code == CursorDown2) {
  680.                            if (Rotate_Matrixr(objptr2, field2, x2, y2, RIGHTFIELD)) {
  681.                               Rotate_Matrixl(objptr2, field2, x2, y2, RIGHTFIELD);
  682.                               Draw_Object(x2, y2, objptr2, FALSE, RIGHTFIELD);
  683.                               Rotate_Matrixr(objptr2, field2, x2, y2, RIGHTFIELD);
  684.                               Draw_Object(x2, y2, objptr2, TRUE, RIGHTFIELD);
  685.                            }
  686.                         } else {
  687.                         if (imsg->Code == CursorLeft2) {
  688.                            if (CollisionLeft(objptr2, field2, x2, y2) == TRUE) {
  689.                               Draw_Object(x2, y2, objptr2, FALSE, RIGHTFIELD);
  690.                               x2 = x2 - 1;
  691.                               Draw_Object(x2, y2, objptr2, TRUE, RIGHTFIELD);
  692.                            }
  693.                         } else {
  694.                         if (imsg->Code == CursorRight2) {
  695.                            if (CollisionRight(objptr2, field2, x2, y2) == TRUE) {
  696.                               Draw_Object(x2, y2, objptr2, FALSE, RIGHTFIELD);
  697.                               x2=x2+1;
  698.                               Draw_Object(x2, y2, objptr2, TRUE, RIGHTFIELD);
  699.                            }
  700.                         } else {
  701.                         if (imsg->Code == NormalSpace2) {
  702.                            if (!SpacePressed2) {
  703.                               AbortIO((struct IORequest *) TimerIO2);
  704.                               WaitIO((struct IORequest *) TimerIO2);
  705.                               SpacePressed2 = TRUE;
  706.                               oldtime2 = time2;
  707.                               time2 = pulldownticks;
  708.                            }
  709.                         } else {
  710.                         if (imsg->Code == QuickSpace2) {
  711.                            AbortIO((struct IORequest *) TimerIO2);
  712.                            WaitIO((struct IORequest *) TimerIO2);
  713.                            oldtime2 = time2;
  714.                            time2 = 0;
  715.                         }
  716.                         }}}}}}
  717.                      else {
  718.                         if (SpacePressed2) {
  719.                           SpacePressed2 = FALSE;
  720.                            time2 = oldtime2;
  721.                         }
  722.                         if (SpacePressed) {
  723.                           SpacePressed = FALSE;
  724.                            time = oldtime;
  725.                         }
  726.  
  727.                      }
  728.                   }}}}}
  729.                   break;
  730.             }
  731.             ReplyMsg((struct Message *)imsg);
  732.          }
  733.       }
  734.    }
  735.  
  736.    closeall();
  737.    return(0);
  738. }
  739.  
  740.  
  741.  
  742. /*
  743. ** Fragt die Kollision nach rechts ab
  744. ** FALSE, wenn Object oder rechte Wand im Weg
  745. ** TRUE , wenn Object nach rechts verschoben werden kann
  746. */
  747. BOOL CollisionRight(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y)
  748. {
  749.    short i,j;
  750.  
  751.    for (j=3; j>=0; j--)
  752.       for (i=0; i<4; i++) {
  753.          if ((objptr->objData[i][j] > 0) && (field[y+i-1][j+x+1] != 0))
  754.             return(FALSE);
  755.       }
  756.    return(TRUE);
  757. }
  758.  
  759.  
  760.  
  761. /*
  762. ** Fragt die Kollision nach links ab
  763. ** FALSE, wenn Object oder linke Wand im Weg
  764. ** TRUE , wenn Object nach links verschoben werden kann
  765. */
  766. BOOL CollisionLeft(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y)
  767. {
  768.    short i,j;
  769.  
  770.    for (j=0; j<4; j++)
  771.       for (i=0; i<4; i++) {
  772.          if ((objptr->objData[i][j] > 0) && (field[y+i-1][j+x-1] != 0))
  773.             return(FALSE);
  774.       }
  775.    return(TRUE);
  776. }
  777.  
  778.  
  779.  
  780. /*
  781. ** Fragt die Kollision nach unten ab
  782. ** FALSE, wenn Object oder Boden im Weg
  783. ** TRUE , wenn Object nach unten verschoben werden kann
  784. */
  785. BOOL CollisionDown(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y, BOOL RightOrLeft)
  786. {
  787.    short i,j;
  788.  
  789.    for (j=0; j<4; j++)
  790.       for (i=0; i<4; i++) {
  791.          if ((objptr->objData[i][j] > 0) && (field[y+i][j+x] != 0)) {
  792.             Score = Score + Level;
  793.             SetNewMatrix(objptr, field, x, y);
  794.             CleanUp(field, RightOrLeft);
  795.             return(FALSE);
  796.          }
  797.       }
  798.    return(TRUE);
  799. }
  800.  
  801.  
  802.  
  803. void openall(void)
  804. {
  805.    if ((TimerMP = CreatePort(NULL, NULL)) == NULL)
  806.       closeout("Couldn't create messageport", RETURN_FAIL);
  807.  
  808.    if ((TimerIO = (struct timerequest *) CreateExtIO(TimerMP, sizeof(struct timerequest))) == NULL)
  809.       closeout("Couldn't create IOrequest", RETURN_FAIL);
  810.  
  811.    if ((TimerError = OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *) TimerIO, 0L)) != NULL)
  812.       closeout("Couldn't open timer.device", RETURN_FAIL);
  813.  
  814.    if (TwoPlayer) {
  815.       if ((TimerMP2 = CreatePort(NULL, NULL)) == NULL)
  816.          closeout("Couldn't create messageport", RETURN_FAIL);
  817.  
  818.       if ((TimerIO2 = (struct timerequest *) CreateExtIO(TimerMP2, sizeof(struct timerequest))) == NULL)
  819.          closeout("Couldn't create IOrequest", RETURN_FAIL);
  820.  
  821.       if ((TimerError2 = OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *) TimerIO2, 0L)) != NULL)
  822.          closeout("Couldn't open timer.device", RETURN_FAIL);
  823.    }
  824.  
  825.    if ((KeymapBase = OpenLibrary("keymap.library", 37)) == NULL)
  826.       closeout("Kickstart 2.0 required",RETURN_FAIL);
  827.  
  828.    if ((IntuitionBase = OpenLibrary("intuition.library", 37)) == NULL)
  829.       closeout("Can't open intuition",RETURN_FAIL);
  830.  
  831.    if ((font = OpenDiskFont(&helvetica13)) == NULL)
  832.       closeout("Failed to open Helvetica 13", RETURN_FAIL);
  833.  
  834.    if ((font2 = OpenDiskFont(&topaz8)) == NULL)
  835.       closeout("Failed to open Topaz 8", RETURN_FAIL);
  836.  
  837.    if ((myscreen = LockPubScreen(NULL)) == NULL)
  838.       closeout("Couldn't lock default public screen", RETURN_FAIL);
  839.  
  840.    if ((myscreen->Height) < 400)
  841.       UseLace = FALSE;
  842.  
  843.    if ((VisualInfo = GetVisualInfo(myscreen, TAG_END)) == NULL)
  844.       closeout("GetVisualInfo() failed", RETURN_FAIL);
  845. }
  846.  
  847.  
  848.  
  849. void closeall(void)
  850. {
  851.    AbortIO((struct IORequest *) TimerIO);
  852.    WaitIO((struct IORequest *) TimerIO);
  853.  
  854.    if (window)
  855.       CloseWindow(window);
  856.  
  857.    if (TetrisGList)
  858.       FreeGadgets(TetrisGList);
  859.  
  860.    if (VisualInfo)
  861.       FreeVisualInfo(VisualInfo);
  862.  
  863.    if (myscreen)
  864.       UnlockPubScreen(NULL, myscreen);
  865.  
  866.    if (IntuitionBase)
  867.       CloseLibrary(IntuitionBase);
  868.  
  869.    if (KeymapBase)
  870.       CloseLibrary(KeymapBase);
  871.  
  872.    if (!TimerError)
  873.       CloseDevice((struct IORequest *) TimerIO);
  874.  
  875.    if (TimerIO)
  876.       DeleteExtIO((struct IORequest *) TimerIO);
  877.  
  878.    if (TimerMP)
  879.       DeletePort(TimerMP);
  880.  
  881.    if (TwoPlayer) {
  882.       if (!TimerError2)
  883.          CloseDevice((struct IORequest *) TimerIO2);
  884.  
  885.       if (TimerIO2)
  886.          DeleteExtIO((struct IORequest *) TimerIO2);
  887.  
  888.       if (TimerMP2)
  889.          DeletePort(TimerMP2);
  890.    }
  891.  
  892.    exit(0);
  893. }
  894.  
  895.  
  896.  
  897. void closeout(UBYTE *errstring, LONG rc)
  898. {
  899.    struct EasyStruct myES = {
  900.       sizeof(struct EasyStruct),
  901.       0,
  902.       "WBTRIS Error",
  903.       "Error: %s\n",
  904.       "OK",
  905.    };
  906.  
  907.    if (*errstring)
  908.       EasyRequest(NULL, &myES, NULL, errstring);
  909.  
  910.     closeall();
  911.     exit(rc);
  912. }
  913.  
  914.  
  915.  
  916. BOOL Rotate_Matrixr(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y, BOOL RightOrLeft)
  917. {
  918.    short i, j;
  919.    struct obj b[1];
  920.  
  921.    b[0].objData[3][0] = objptr->objData[0][0];
  922.    b[0].objData[2][0] = objptr->objData[0][1];
  923.    b[0].objData[1][0] = objptr->objData[0][2];
  924.    b[0].objData[0][0] = objptr->objData[0][3];
  925.    b[0].objData[3][1] = objptr->objData[1][0];
  926.    b[0].objData[2][1] = objptr->objData[1][1];
  927.    b[0].objData[1][1] = objptr->objData[1][2];
  928.    b[0].objData[0][1] = objptr->objData[1][3];
  929.    b[0].objData[3][2] = objptr->objData[2][0];
  930.    b[0].objData[2][2] = objptr->objData[2][1];
  931.    b[0].objData[1][2] = objptr->objData[2][2];
  932.    b[0].objData[0][2] = objptr->objData[2][3];
  933.    b[0].objData[3][3] = objptr->objData[3][0];
  934.    b[0].objData[2][3] = objptr->objData[3][1];
  935.    b[0].objData[1][3] = objptr->objData[3][2];
  936.    b[0].objData[0][3] = objptr->objData[3][3];
  937.  
  938.    if ((CollisionRight(b, field, x-1, y) == TRUE) && (CollisionLeft(b, field, x+1, y) == TRUE) && (CollisionDown(b, field, x, y-1, RightOrLeft) == TRUE)) {
  939.       for (i=0; i<4; i++)
  940.          for (j=0; j<4; j++)
  941.             objptr->objData[i][j] = b[0].objData[i][j];
  942.       return(TRUE);
  943.    }
  944.    return(FALSE);
  945. }
  946.  
  947.  
  948.  
  949. BOOL Rotate_Matrixl(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y, BOOL RightOrLeft)
  950. {
  951.    short i, j;
  952.    struct obj b[1];
  953.  
  954.    b[0].objData[0][3] = objptr->objData[0][0];
  955.    b[0].objData[1][3] = objptr->objData[0][1];
  956.    b[0].objData[2][3] = objptr->objData[0][2];
  957.    b[0].objData[3][3] = objptr->objData[0][3];
  958.    b[0].objData[0][2] = objptr->objData[1][0];
  959.    b[0].objData[1][2] = objptr->objData[1][1];
  960.    b[0].objData[2][2] = objptr->objData[1][2];
  961.    b[0].objData[3][2] = objptr->objData[1][3];
  962.    b[0].objData[0][1] = objptr->objData[2][0];
  963.    b[0].objData[1][1] = objptr->objData[2][1];
  964.    b[0].objData[2][1] = objptr->objData[2][2];
  965.    b[0].objData[3][1] = objptr->objData[2][3];
  966.    b[0].objData[0][0] = objptr->objData[3][0];
  967.    b[0].objData[1][0] = objptr->objData[3][1];
  968.    b[0].objData[2][0] = objptr->objData[3][2];
  969.    b[0].objData[3][0] = objptr->objData[3][3];
  970.  
  971.    if ((CollisionRight(b, field, x-1, y) == TRUE) && (CollisionLeft(b, field, x+1, y) == TRUE) && (CollisionDown(b, field, x, y-1, RightOrLeft) == TRUE)) {
  972.       for (i=0; i<4; i++)
  973.          for (j=0; j<4; j++)
  974.             objptr->objData[i][j] = b[0].objData[i][j];
  975.       return(TRUE);
  976.    }
  977.    return(FALSE);
  978. }
  979.  
  980.  
  981.  
  982. void Draw_NextObject(struct obj *objptr, BOOL FieldRight)
  983. {
  984.    short i,j;
  985.  
  986.    for (i=0; i<4; i++) {
  987.       for (j=0; j<4; j++)
  988.          if (objptr->objData[i][j] > 0)
  989.             Draw_Box(j-5, i, objptr->color, TRUE, FieldRight);
  990.    }
  991. }
  992.  
  993.  
  994.  
  995. void ClearNextField(BOOL RightOrLeft)
  996. {
  997.    short i,j;
  998.  
  999.    for (i=0; i<4; i++) {
  1000.       for (j=0; j<4; j++)
  1001.             Draw_Box(j-5, i, 0, FALSE, RightOrLeft);
  1002.    }
  1003. }
  1004.  
  1005.  
  1006.  
  1007. void Draw_Object(int x, int y, struct obj *objptr, BOOL malen, BOOL RightOrLeft)
  1008. {
  1009.    short i,j;
  1010.  
  1011.    for (i=0; i<4; i++) {
  1012.       for (j=0; j<4; j++)
  1013.          if (objptr->objData[i][j] > 0)
  1014.             Draw_Box(x+j, y+i-1, objptr->color, malen, RightOrLeft);
  1015.    }
  1016. }
  1017.  
  1018.  
  1019.  
  1020. void Draw_Box(int x, int y, int color, int malen, BOOL RightOrLeft)
  1021. {
  1022.    int TwoPLayerOffSet;
  1023.  
  1024.    if (RightOrLeft)
  1025.       TwoPLayerOffSet = boxxsize*XSIZE + FieldsSpace;
  1026.    else
  1027.       TwoPLayerOffSet = 0;
  1028.  
  1029.    if (UseLace) {
  1030.       if (malen == TRUE) {
  1031.          switch(color) {
  1032.             case 1:
  1033.                DrawImage(rp, &GruenWeiss, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1034.                break;
  1035.             case 2:
  1036.                DrawImage(rp, &GruenWeissSchach, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1037.                break;
  1038.             case 3:
  1039.                DrawImage(rp, &GruenWeissSchraeg, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1040.                break;
  1041.             case 4:
  1042.                DrawImage(rp, &Schwarz, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1043.                break;
  1044.             case 5:
  1045.                DrawImage(rp, &SchwarzGruen, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1046.                break;
  1047.             case 6:
  1048.                DrawImage(rp, &SchwarzWeiss, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1049.                break;
  1050.             case 7:
  1051.                DrawImage(rp, &Gruen, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1052.                break;
  1053.          }
  1054.       } else {
  1055.          switch(color) {
  1056.             case 0:
  1057.                SetAPen(rp, 0);
  1058.                RectFill(rp, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize, MAINXOFFSET + x*boxxsize + BOXXSIZE + TwoPLayerOffSet, YOffSet + y*boxysize + BOXYSIZE);
  1059.                break;
  1060.             case 1:
  1061.                EraseImage(rp, &GruenWeiss, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1062.                break;
  1063.             case 2:
  1064.                EraseImage(rp, &GruenWeissSchach, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1065.                break;
  1066.             case 3:
  1067.                EraseImage(rp, &GruenWeissSchraeg, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1068.                break;
  1069.             case 4:
  1070.                EraseImage(rp, &Schwarz, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1071.                break;
  1072.             case 5:
  1073.                EraseImage(rp, &SchwarzGruen, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1074.                break;
  1075.             case 6:
  1076.                EraseImage(rp, &SchwarzWeiss, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1077.                break;
  1078.             case 7:
  1079.                EraseImage(rp, &Gruen, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1080.                break;
  1081.          }
  1082.       }
  1083.    } else {
  1084.       if (malen == TRUE) {
  1085.          switch(color) {
  1086.             case 1:
  1087.                DrawImage(rp, &GruenWeissNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1088.                break;
  1089.             case 2:
  1090.                DrawImage(rp, &GruenWeissSchachNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1091.                break;
  1092.             case 3:
  1093.                DrawImage(rp, &GruenWeissSchraegNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1094.                break;
  1095.             case 4:
  1096.                DrawImage(rp, &SchwarzNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1097.                break;
  1098.             case 5:
  1099.                DrawImage(rp, &SchwarzGruenNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1100.                break;
  1101.             case 6:
  1102.                DrawImage(rp, &SchwarzWeissNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1103.                break;
  1104.             case 7:
  1105.                DrawImage(rp, &GruenNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1106.                break;
  1107.          }
  1108.       } else {
  1109.          switch(color) {
  1110.             case 0:
  1111.                SetAPen(rp, 0);
  1112.                RectFill(rp, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize, MAINXOFFSET + x*boxxsize + BOXXSIZE + TwoPLayerOffSet, YOffSet + y*boxysize + BOXYSIZE);
  1113.                break;
  1114.             case 1:
  1115.                EraseImage(rp, &GruenWeissNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1116.                break;
  1117.             case 2:
  1118.                EraseImage(rp, &GruenWeissSchachNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1119.                break;
  1120.             case 3:
  1121.                EraseImage(rp, &GruenWeissSchraegNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1122.                break;
  1123.             case 4:
  1124.                EraseImage(rp, &SchwarzNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1125.                break;
  1126.             case 5:
  1127.                EraseImage(rp, &SchwarzGruenNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1128.                break;
  1129.             case 6:
  1130.                EraseImage(rp, &SchwarzWeissNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1131.                break;
  1132.             case 7:
  1133.                EraseImage(rp, &GruenNI, MAINXOFFSET + x*boxxsize + TwoPLayerOffSet, YOffSet + y*boxysize);
  1134.                break;
  1135.          }
  1136.       }
  1137.    }
  1138. }
  1139.  
  1140.  
  1141.  
  1142. struct obj *RandomObject(BOOL RightOrLeft)
  1143. {
  1144.    static ULONG RandomResult = 0L; /* So the last random-number is still stored ! */
  1145.    ULONG Sec,Mic;
  1146.  
  1147.    CurrentTime((LONG *)&Sec,(LONG *)&Mic);
  1148.  
  1149.    RandomResult *= Sec;
  1150.    RandomResult += Mic;
  1151.  
  1152.    while (RandomResult > 32767L) RandomResult = RandomResult>>1;
  1153.  
  1154.    RandomResult = RandomResult % 7;
  1155.  
  1156.    UpdateStatistic(RandomResult);
  1157.  
  1158.    if (RightOrLeft == LEFTFIELD) {
  1159.       switch(RandomResult) {
  1160.          case 0:
  1161.             return(&objects[1]);
  1162.             break;
  1163.          case 1:
  1164.             return(&objects[2]);
  1165.             break;
  1166.          case 2:
  1167.             return(&objects[3]);
  1168.             break;
  1169.          case 3:
  1170.             return(&objects[4]);
  1171.             break;
  1172.          case 4:
  1173.             return(&objects[5]);
  1174.             break;
  1175.          case 5:
  1176.             return(&objects[6]);
  1177.             break;
  1178.          default:
  1179.             return(&objects[7]);
  1180.       }
  1181.    } else {
  1182.       switch(RandomResult) {
  1183.          case 0:
  1184.             return(&objects2[1]);
  1185.             break;
  1186.          case 1:
  1187.             return(&objects2[2]);
  1188.             break;
  1189.          case 2:
  1190.             return(&objects2[3]);
  1191.             break;
  1192.          case 3:
  1193.             return(&objects2[4]);
  1194.             break;
  1195.          case 4:
  1196.             return(&objects2[5]);
  1197.             break;
  1198.          case 5:
  1199.             return(&objects2[6]);
  1200.             break;
  1201.          default:
  1202.             return(&objects2[7]);
  1203.       }
  1204.    }
  1205. }
  1206.  
  1207.  
  1208.  
  1209. void DrawWindow(void)
  1210. {
  1211.    /* Mainfield */
  1212.    if (UseLace)
  1213.       DrawBevelBox(rp, MAINXOFFSET+14, YOffSet-2, (XSIZE+1)*boxxsize-10, YSIZE*boxysize+5, GTBB_Recessed, TRUE, GT_VisualInfo, VisualInfo);
  1214.    else
  1215.       DrawBevelBox(rp, MAINXOFFSET+13, YOffSet-2, (XSIZE+1)*boxxsize-10, YSIZE*boxysize+5, GTBB_Recessed, TRUE, GT_VisualInfo, VisualInfo);
  1216.  
  1217.    /* Next Object Field */
  1218.    DrawBevelBox(rp, NEXTXOFFSET+14, YOffSet-2, 5*boxxsize-10, 4*boxysize+4, GTBB_Recessed, TRUE, GT_VisualInfo, VisualInfo);
  1219.  
  1220.    /* Logo */
  1221.    if (UseLace)
  1222.       DrawImage(rp, &logo, LGXOS + 20, YOffSet + 300);
  1223.    else
  1224.       DrawImage(rp, &logo, LGXOS, YOffSet);
  1225.  
  1226. /*
  1227.    if (UseLace)
  1228.       DrawBevelBox(rp, MAINXOFFSET+14, YOffSet-2, (XSIZE+1)*boxxsize-10, YSIZE*boxysize+5, GT_VisualInfo, VisualInfo);
  1229.    else
  1230.       DrawBevelBox(rp, MAINXOFFSET+13, YOffSet-2, (XSIZE+1)*boxxsize-10, YSIZE*boxysize+5, GT_VisualInfo, VisualInfo);
  1231.  
  1232.    DrawBevelBox(rp, NEXTXOFFSET+14, YOffSet-2, 5*boxxsize-10, 4*boxysize+4, GTBB_Recessed, TRUE, GT_VisualInfo, VisualInfo);
  1233.  
  1234.    if (UseLace)
  1235.       DrawImage(rp, &logo, LGXOS + 20, YOffSet + LGYOS + 300);
  1236.    else
  1237.       DrawImage(rp, &logo, LGXOS, YOffSet - 2);
  1238. */
  1239.  
  1240.    /*
  1241.    ** Only for 2 player mode
  1242.    */
  1243.    if (TwoPlayer) {
  1244.       /* Mainfield */
  1245.       if (UseLace)
  1246.          DrawBevelBox(rp, XSIZE*boxxsize + MAINXOFFSET+14 + FieldsSpace, YOffSet-2, (XSIZE+1)*boxxsize-10, YSIZE*boxysize+5, GTBB_Recessed, TRUE, GT_VisualInfo, VisualInfo);
  1247.       else
  1248.          DrawBevelBox(rp, XSIZE*boxxsize + MAINXOFFSET+13 + FieldsSpace, YOffSet-2, (XSIZE+1)*boxxsize-10, YSIZE*boxysize+5, GTBB_Recessed, TRUE, GT_VisualInfo, VisualInfo);
  1249.  
  1250.       /* Next Object Field */
  1251.       DrawBevelBox(rp, XSIZE*boxxsize + NEXTXOFFSET+14 + FieldsSpace, YOffSet-2, 5*boxxsize-10, 4*boxysize+4, GTBB_Recessed, TRUE, GT_VisualInfo, VisualInfo);
  1252.    }
  1253. }
  1254.  
  1255.  
  1256.  
  1257. void SetNewMatrix(struct obj *objptr, int field[YSIZE+1][XSIZE+2], int x, int y)
  1258. {
  1259.    short line, column;
  1260.  
  1261.    for (line=0; line<4; line++)
  1262.       for (column=0; column<4; column++) {
  1263.          if (objptr->objData[line][column] == 1)
  1264.             field[y+line-1][x+column] = objptr->color;
  1265.       }
  1266. }
  1267.  
  1268.  
  1269.  
  1270. void CleanUp(int ThisField[YSIZE+1][XSIZE+2], BOOL RightOrLeft)
  1271. {
  1272.    int i, j, line, column;
  1273.    BOOL Update = FALSE;
  1274.    BOOL KeineNull = TRUE;
  1275.    int LinesToRemove = 0;
  1276.  
  1277.    Lines = 0;
  1278.    for (line=1; line < YSIZE; line++) {
  1279.       for (column=1; column < XSIZE+1; column++)
  1280.          if (ThisField[line][column] == 0)
  1281.             KeineNull = FALSE;
  1282.  
  1283.       if (KeineNull == TRUE)
  1284.       {
  1285.          Lines++;
  1286.          LinesToRemove++;
  1287.          Update = TRUE;
  1288.          for (j=line; j>0; j--)
  1289.             for (i=1; i<XSIZE+1; i++)
  1290.                ThisField[j][i] = ThisField[j-1][i];
  1291.       }
  1292.       KeineNull = TRUE;
  1293.    }
  1294.  
  1295.    if (Update == TRUE) {
  1296.       if (TwoPlayer ) {
  1297.          if (LinesToRemove > 0) {
  1298.             if (RightOrLeft == RIGHTFIELD)
  1299.                PutRows(field, LEFTFIELD, LinesToRemove);
  1300.             else
  1301.                PutRows(field2, RIGHTFIELD, LinesToRemove);
  1302.          }
  1303.       }
  1304.       ReDrawField(ThisField, RightOrLeft);
  1305.    }
  1306.  
  1307.    LineCounter = LineCounter + Lines;
  1308.    Level = LineCounter / 10 + LevelOffset;
  1309.    if (Level >= 20)
  1310.       oldtime = 0;
  1311.    else
  1312.       oldtime = DEFAULTTICKS - Level*2;
  1313.    time = oldtime;
  1314.  
  1315.    if (TwoPlayer) {
  1316.       if (Level >= 20)
  1317.          oldtime2 = 0;
  1318.       else
  1319.          oldtime2 = DEFAULTTICKS - Level*2;
  1320.       time2 = oldtime2;
  1321.    }
  1322.  
  1323.    if (Level == 0)
  1324.       Score = Score + 5*Lines*Lines*(Level+1);
  1325.    else
  1326.       Score = Score + 10*Lines*Lines*Level;
  1327.  
  1328.    if (Score > Highscore)
  1329.       Highscore = Score;
  1330.  
  1331.    GT_SetGadgetAttrs(TetrisGadgets[GD_HighscoreGadget], window, NULL,
  1332.                      GTNM_Number, (ULONG)Highscore,
  1333.                      TAG_END);
  1334.    GT_SetGadgetAttrs(TetrisGadgets[GD_ScoreGadget], window, NULL,
  1335.                      GTNM_Number, (ULONG)Score,
  1336.                      TAG_END);
  1337.    GT_SetGadgetAttrs(TetrisGadgets[GD_LevelGadget], window, NULL,
  1338.                      GTNM_Number, (ULONG)Level,
  1339.                      TAG_END);
  1340.    GT_SetGadgetAttrs(TetrisGadgets[GD_LineGadget], window, NULL,
  1341.                      GTNM_Number, (ULONG)LineCounter,
  1342.                      TAG_END);
  1343. }
  1344.  
  1345.  
  1346.  
  1347. /*
  1348. ** Ist der obere Rand erreicht, dann ist das Spiel zu Ende
  1349. ** TRUE,  wenn oberer Rand erreicht
  1350. ** FALSE, wenn nicht
  1351. */
  1352. BOOL GameOver(int field[YSIZE+1][XSIZE+2],BOOL lockname)
  1353. {
  1354.    int column;
  1355.  
  1356.    for (column=0; column<=XSIZE; column++) {
  1357.       if (field[1][column] > 0) {
  1358.          if (Score > Highscore)
  1359.          Highscore = Score;
  1360.  
  1361.          if ((lockname == FALSE) || (strlen(Name) == 0))
  1362.             AskForName();
  1363.          HiscoreList(Name, Level, Score, LineCounter, window->LeftEdge, window->TopEdge, SAVEHISCORE);
  1364.  
  1365.          if ((AskContinue()) == TRUE) {
  1366.              Score = 0;
  1367.              LineCounter = 0;
  1368.              Level = LevelOffset;
  1369.              NewGame(field, TRUE, FALSE);
  1370.          }
  1371.          else
  1372.             return(TRUE);
  1373.       }
  1374.    }
  1375.    return(FALSE);
  1376. }
  1377.  
  1378.  
  1379.  
  1380. /*
  1381. ** Hier wird den Objekten die Form und die Farbe gegeben
  1382. */
  1383. void InitObjects(void)
  1384. {
  1385.    FILE *fp = NULL;
  1386.    short ObjectNumber = 1;
  1387.    short line = 0;
  1388.    short column = 0;
  1389.    int number;
  1390.  
  1391.    objects[0].objData[0][0] = 0; objects[0].objData[0][1] = 0; objects[0].objData[0][2] = 0; objects[0].objData[0][3] = 0;
  1392.    objects[0].objData[1][0] = 0; objects[0].objData[1][1] = 0; objects[0].objData[1][2] = 0; objects[0].objData[1][3] = 0;
  1393.    objects[0].objData[2][0] = 0; objects[0].objData[2][1] = 0; objects[0].objData[2][2] = 0; objects[0].objData[2][3] = 0;
  1394.    objects[0].objData[3][0] = 0; objects[0].objData[3][1] = 0; objects[0].objData[3][2] = 0; objects[0].objData[3][3] = 0;
  1395.    objects[0].color = 0;
  1396.  
  1397.    objects2[0].objData[0][0] = 0; objects2[0].objData[0][1] = 0; objects2[0].objData[0][2] = 0; objects2[0].objData[0][3] = 0;
  1398.    objects2[0].objData[1][0] = 0; objects2[0].objData[1][1] = 0; objects2[0].objData[1][2] = 0; objects2[0].objData[1][3] = 0;
  1399.    objects2[0].objData[2][0] = 0; objects2[0].objData[2][1] = 0; objects2[0].objData[2][2] = 0; objects2[0].objData[2][3] = 0;
  1400.    objects2[0].objData[3][0] = 0; objects2[0].objData[3][1] = 0; objects2[0].objData[3][2] = 0; objects2[0].objData[3][3] = 0;
  1401.    objects2[0].color = 0;
  1402.  
  1403.    if ((strlen(TileFile) != 0) && ((fp = fopen(TileFile, "r")) != NULL)) {
  1404.          while (ObjectNumber <= 7) {
  1405.             for (line=0; line<=3; line++) {
  1406.                for (column=0; column<=3; column++) {
  1407.                   number = getc(fp);
  1408.                   while ((number != '0') && (number != '1') && (number != EOF))
  1409.                      number = getc(fp);
  1410.                   if (number == '1') {
  1411.                      objects[ObjectNumber].objData[line][column] = 1;
  1412.                      objects2[ObjectNumber].objData[line][column] = 1;
  1413.                   }
  1414.                   if (number == '0') {
  1415.                      objects[ObjectNumber].objData[line][column] = 0;
  1416.                      objects2[ObjectNumber].objData[line][column] = 0;
  1417.                   }
  1418.                }
  1419.             }
  1420.             objects[ObjectNumber].color = ObjectNumber;
  1421.             objects2[ObjectNumber].color = ObjectNumber;
  1422.             ObjectNumber++;
  1423.          }
  1424.          fclose(fp);
  1425.    } else {
  1426.  
  1427.       objects[1].objData[0][0] = 0; objects[1].objData[0][1] = 0; objects[1].objData[0][2] = 0; objects[1].objData[0][3] = 0;
  1428.       objects[1].objData[1][0] = 0; objects[1].objData[1][1] = 1; objects[1].objData[1][2] = 1; objects[1].objData[1][3] = 0;
  1429.       objects[1].objData[2][0] = 0; objects[1].objData[2][1] = 1; objects[1].objData[2][2] = 1; objects[1].objData[2][3] = 0;
  1430.       objects[1].objData[3][0] = 0; objects[1].objData[3][1] = 0; objects[1].objData[3][2] = 0; objects[1].objData[3][3] = 0;
  1431.       objects[1].color = 1;
  1432.  
  1433.       objects[2].objData[0][0] = 0; objects[2].objData[0][1] = 1; objects[2].objData[0][2] = 0; objects[2].objData[0][3] = 0;
  1434.       objects[2].objData[1][0] = 0; objects[2].objData[1][1] = 1; objects[2].objData[1][2] = 0; objects[2].objData[1][3] = 0;
  1435.       objects[2].objData[2][0] = 0; objects[2].objData[2][1] = 1; objects[2].objData[2][2] = 0; objects[2].objData[2][3] = 0;
  1436.       objects[2].objData[3][0] = 0; objects[2].objData[3][1] = 1; objects[2].objData[3][2] = 0; objects[2].objData[3][3] = 0;
  1437.       objects[2].color = 2;
  1438.  
  1439.       objects[3].objData[0][0] = 0; objects[3].objData[0][1] = 0; objects[3].objData[0][2] = 0; objects[3].objData[0][3] = 0;
  1440.       objects[3].objData[1][0] = 0; objects[3].objData[1][1] = 0; objects[3].objData[1][2] = 1; objects[3].objData[1][3] = 0;
  1441.       objects[3].objData[2][0] = 0; objects[3].objData[2][1] = 1; objects[3].objData[2][2] = 1; objects[3].objData[2][3] = 0;
  1442.       objects[3].objData[3][0] = 0; objects[3].objData[3][1] = 0; objects[3].objData[3][2] = 1; objects[3].objData[3][3] = 0;
  1443.       objects[3].color = 3;
  1444.  
  1445.       objects[4].objData[0][0] = 0; objects[4].objData[0][1] = 0; objects[4].objData[0][2] = 0; objects[4].objData[0][3] = 0;
  1446.       objects[4].objData[1][0] = 1; objects[4].objData[1][1] = 1; objects[4].objData[1][2] = 1; objects[4].objData[1][3] = 0;
  1447.       objects[4].objData[2][0] = 0; objects[4].objData[2][1] = 0; objects[4].objData[2][2] = 1; objects[4].objData[2][3] = 0;
  1448.       objects[4].objData[3][0] = 0; objects[4].objData[3][1] = 0; objects[4].objData[3][2] = 0; objects[4].objData[3][3] = 0;
  1449.       objects[4].color = 4;
  1450.  
  1451.       objects[5].objData[0][0] = 0; objects[5].objData[0][1] = 0; objects[5].objData[0][2] = 0; objects[5].objData[0][3] = 0;
  1452.       objects[5].objData[1][0] = 0; objects[5].objData[1][1] = 0; objects[5].objData[1][2] = 1; objects[5].objData[1][3] = 0;
  1453.       objects[5].objData[2][0] = 1; objects[5].objData[2][1] = 1; objects[5].objData[2][2] = 1; objects[5].objData[2][3] = 0;
  1454.       objects[5].objData[3][0] = 0; objects[5].objData[3][1] = 0; objects[5].objData[3][2] = 0; objects[5].objData[3][3] = 0;
  1455.       objects[5].color = 5;
  1456.  
  1457.       objects[6].objData[0][0] = 0; objects[6].objData[0][1] = 1; objects[6].objData[0][2] = 0; objects[6].objData[0][3] = 0;
  1458.       objects[6].objData[1][0] = 0; objects[6].objData[1][1] = 1; objects[6].objData[1][2] = 1; objects[6].objData[1][3] = 0;
  1459.       objects[6].objData[2][0] = 0; objects[6].objData[2][1] = 0; objects[6].objData[2][2] = 1; objects[6].objData[2][3] = 0;
  1460.       objects[6].objData[3][0] = 0; objects[6].objData[3][1] = 0; objects[6].objData[3][2] = 0; objects[6].objData[3][3] = 0;
  1461.       objects[6].color = 6;
  1462.  
  1463.       objects[7].objData[0][0] = 0; objects[7].objData[0][1] = 0; objects[7].objData[0][2] = 0; objects[7].objData[0][3] = 0;
  1464.       objects[7].objData[1][0] = 0; objects[7].objData[1][1] = 0; objects[7].objData[1][2] = 1; objects[7].objData[1][3] = 0;
  1465.       objects[7].objData[2][0] = 0; objects[7].objData[2][1] = 1; objects[7].objData[2][2] = 1; objects[7].objData[2][3] = 0;
  1466.       objects[7].objData[3][0] = 0; objects[7].objData[3][1] = 1; objects[7].objData[3][2] = 0; objects[7].objData[3][3] = 0;
  1467.       objects[7].color = 7;
  1468.  
  1469.  
  1470.       objects2[1].objData[0][0] = 0; objects2[1].objData[0][1] = 0; objects2[1].objData[0][2] = 0; objects2[1].objData[0][3] = 0;
  1471.       objects2[1].objData[1][0] = 0; objects2[1].objData[1][1] = 1; objects2[1].objData[1][2] = 1; objects2[1].objData[1][3] = 0;
  1472.       objects2[1].objData[2][0] = 0; objects2[1].objData[2][1] = 1; objects2[1].objData[2][2] = 1; objects2[1].objData[2][3] = 0;
  1473.       objects2[1].objData[3][0] = 0; objects2[1].objData[3][1] = 0; objects2[1].objData[3][2] = 0; objects2[1].objData[3][3] = 0;
  1474.       objects2[1].color = 1;
  1475.  
  1476.       objects2[2].objData[0][0] = 0; objects2[2].objData[0][1] = 1; objects2[2].objData[0][2] = 0; objects2[2].objData[0][3] = 0;
  1477.       objects2[2].objData[1][0] = 0; objects2[2].objData[1][1] = 1; objects2[2].objData[1][2] = 0; objects2[2].objData[1][3] = 0;
  1478.       objects2[2].objData[2][0] = 0; objects2[2].objData[2][1] = 1; objects2[2].objData[2][2] = 0; objects2[2].objData[2][3] = 0;
  1479.       objects2[2].objData[3][0] = 0; objects2[2].objData[3][1] = 1; objects2[2].objData[3][2] = 0; objects2[2].objData[3][3] = 0;
  1480.       objects2[2].color = 2;
  1481.  
  1482.       objects2[3].objData[0][0] = 0; objects2[3].objData[0][1] = 0; objects2[3].objData[0][2] = 0; objects2[3].objData[0][3] = 0;
  1483.       objects2[3].objData[1][0] = 0; objects2[3].objData[1][1] = 0; objects2[3].objData[1][2] = 1; objects2[3].objData[1][3] = 0;
  1484.       objects2[3].objData[2][0] = 0; objects2[3].objData[2][1] = 1; objects2[3].objData[2][2] = 1; objects2[3].objData[2][3] = 0;
  1485.       objects2[3].objData[3][0] = 0; objects2[3].objData[3][1] = 0; objects2[3].objData[3][2] = 1; objects2[3].objData[3][3] = 0;
  1486.       objects2[3].color = 3;
  1487.  
  1488.       objects2[4].objData[0][0] = 0; objects2[4].objData[0][1] = 0; objects2[4].objData[0][2] = 0; objects2[4].objData[0][3] = 0;
  1489.       objects2[4].objData[1][0] = 1; objects2[4].objData[1][1] = 1; objects2[4].objData[1][2] = 1; objects2[4].objData[1][3] = 0;
  1490.       objects2[4].objData[2][0] = 0; objects2[4].objData[2][1] = 0; objects2[4].objData[2][2] = 1; objects2[4].objData[2][3] = 0;
  1491.       objects2[4].objData[3][0] = 0; objects2[4].objData[3][1] = 0; objects2[4].objData[3][2] = 0; objects2[4].objData[3][3] = 0;
  1492.       objects2[4].color = 4;
  1493.  
  1494.       objects2[5].objData[0][0] = 0; objects2[5].objData[0][1] = 0; objects2[5].objData[0][2] = 0; objects2[5].objData[0][3] = 0;
  1495.       objects2[5].objData[1][0] = 0; objects2[5].objData[1][1] = 0; objects2[5].objData[1][2] = 1; objects2[5].objData[1][3] = 0;
  1496.       objects2[5].objData[2][0] = 1; objects2[5].objData[2][1] = 1; objects2[5].objData[2][2] = 1; objects2[5].objData[2][3] = 0;
  1497.       objects2[5].objData[3][0] = 0; objects2[5].objData[3][1] = 0; objects2[5].objData[3][2] = 0; objects2[5].objData[3][3] = 0;
  1498.       objects2[5].color = 5;
  1499.  
  1500.       objects2[6].objData[0][0] = 0; objects2[6].objData[0][1] = 1; objects2[6].objData[0][2] = 0; objects2[6].objData[0][3] = 0;
  1501.       objects2[6].objData[1][0] = 0; objects2[6].objData[1][1] = 1; objects2[6].objData[1][2] = 1; objects2[6].objData[1][3] = 0;
  1502.       objects2[6].objData[2][0] = 0; objects2[6].objData[2][1] = 0; objects2[6].objData[2][2] = 1; objects2[6].objData[2][3] = 0;
  1503.       objects2[6].objData[3][0] = 0; objects2[6].objData[3][1] = 0; objects2[6].objData[3][2] = 0; objects2[6].objData[3][3] = 0;
  1504.       objects2[6].color = 6;
  1505.  
  1506.       objects2[7].objData[0][0] = 0; objects2[7].objData[0][1] = 0; objects2[7].objData[0][2] = 0; objects2[7].objData[0][3] = 0;
  1507.       objects2[7].objData[1][0] = 0; objects2[7].objData[1][1] = 0; objects2[7].objData[1][2] = 1; objects2[7].objData[1][3] = 0;
  1508.       objects2[7].objData[2][0] = 0; objects2[7].objData[2][1] = 1; objects2[7].objData[2][2] = 1; objects2[7].objData[2][3] = 0;
  1509.       objects2[7].objData[3][0] = 0; objects2[7].objData[3][1] = 1; objects2[7].objData[3][2] = 0; objects2[7].objData[3][3] = 0;
  1510.       objects2[7].color = 7;
  1511.    }
  1512. }
  1513.  
  1514.  
  1515. /*
  1516. ** Das Programm kann angehalten werden
  1517. */
  1518. BOOL Pause(void)
  1519. {
  1520.    BOOL                 Done = FALSE;
  1521.    struct IntuiMessage *imsg = NULL;
  1522.    struct Gadget       *gad = NULL;
  1523.    int                  line,column;
  1524.  
  1525.    GT_SetGadgetAttrs(TetrisGadgets[GD_PauseGadget], window, NULL,
  1526.                      GTCY_Labels, &CYCLELabels[1], TAG_END);
  1527.    GT_SetGadgetAttrs(TetrisGadgets[GD_NewGadget], window, NULL,
  1528.                      GA_Disabled, TRUE, TAG_END);
  1529.    GT_SetGadgetAttrs(TetrisGadgets[GD_OptGadget], window, NULL,
  1530.                      GA_Disabled, TRUE, TAG_END);
  1531.  
  1532.    HideField();
  1533.  
  1534.    while(!Done)
  1535.    {
  1536.       Wait(1L << window->UserPort->mp_SigBit);
  1537.  
  1538.       while (imsg = (struct IntuiMessage *)GetMsg(window->UserPort)) {
  1539.          switch(imsg->Class) {
  1540.             case IDCMP_GADGETUP:
  1541.                gad = (struct Gadget *)imsg->IAddress;
  1542.                switch(gad->GadgetID) {
  1543.                   case GD_PauseGadget:
  1544.                      GT_SetGadgetAttrs(TetrisGadgets[GD_PauseGadget], window, NULL,
  1545.                                        GA_Disabled, FALSE, TAG_END);
  1546.                      GT_SetGadgetAttrs(TetrisGadgets[GD_NewGadget], window, NULL,
  1547.                                        GA_Disabled, FALSE, TAG_END);
  1548.                      GT_SetGadgetAttrs(TetrisGadgets[GD_OptGadget], window, NULL,
  1549.                                        GA_Disabled, FALSE, TAG_END);
  1550.                      GT_SetGadgetAttrs(TetrisGadgets[GD_PauseGadget], window, NULL,
  1551.                                        GTCY_Labels, &CYCLELabels[0], TAG_END);
  1552.                      Done = TRUE;
  1553.                      break;
  1554.                   case GD_StatGadget:
  1555.                      statistic(window->LeftEdge, window->TopEdge, obj1, obj2, obj3, obj4, obj5, obj6, obj7);
  1556.                      break;
  1557.                   case GD_ShowScoreGadget:
  1558.                      HiscoreList(Name, Level, Score, LineCounter, window->LeftEdge, window->TopEdge, SHOWHISCORE);
  1559.                      break;
  1560.                }
  1561.                break;
  1562.  
  1563.             case IDCMP_REFRESHWINDOW:
  1564.                GT_BeginRefresh(window);
  1565.                GT_EndRefresh(window, TRUE);
  1566.                break;
  1567.  
  1568.             case IDCMP_CLOSEWINDOW:
  1569.                QuitGame();
  1570.                break;
  1571.          }
  1572.          ReplyMsg((struct Message *)imsg);
  1573.       }
  1574.    }
  1575.    if (UseLace)
  1576.       EraseImage(rp, &Pausebrush, 190,150);
  1577.    else
  1578.       EraseImage(rp, &Pausebrush, 310,85);
  1579.  
  1580.    if (TwoPlayer) {
  1581.       if (UseLace)
  1582.          EraseImage(rp, &Pausebrush, 190 + XSIZE*boxxsize + FieldsSpace,150);
  1583.       else
  1584.          EraseImage(rp, &Pausebrush, 310 + XSIZE*boxxsize + FieldsSpace,85);
  1585.    }
  1586.  
  1587.    ReDrawField(field, LEFTFIELD);
  1588.    ReDrawField(field2, RIGHTFIELD);
  1589.  
  1590.    if (TwoPlayer) {
  1591.       for (line=1; line < YSIZE; line++) {
  1592.          for (column=1; column < XSIZE+1; column++) {
  1593.             switch(field2[line][column]) {
  1594.                case 0:
  1595.                   Draw_Box(column, line, 0, FALSE, RIGHTFIELD);
  1596.                   break;
  1597.                case 1:
  1598.                   Draw_Box(column, line, 1, TRUE, RIGHTFIELD);
  1599.                   break;
  1600.                case 2:
  1601.                   Draw_Box(column, line, 2, TRUE, RIGHTFIELD);
  1602.                   break;
  1603.                case 3:
  1604.                   Draw_Box(column, line, 3, TRUE, RIGHTFIELD);
  1605.                   break;
  1606.                case 4:
  1607.                   Draw_Box(column, line, 4, TRUE, RIGHTFIELD);
  1608.                   break;
  1609.                case 5:
  1610.                   Draw_Box(column, line, 5, TRUE, RIGHTFIELD);
  1611.                   break;
  1612.                case 6:
  1613.                   Draw_Box(column, line, 6, TRUE, RIGHTFIELD);
  1614.                   break;
  1615.                case 7:
  1616.                   Draw_Box(column, line, 7, TRUE, RIGHTFIELD);
  1617.                   break;
  1618.             }
  1619.          }
  1620.       }
  1621.    }
  1622.    return(FALSE);
  1623. }
  1624.  
  1625.  
  1626.  
  1627. /*
  1628. ** Ein neues Spiel starten
  1629. */
  1630. void NewGame(int ThisField[YSIZE+1][XSIZE+2], BOOL vongameover, BOOL vonoptions)
  1631. {
  1632.    int line, column;
  1633.  
  1634.    AbortIO((struct IORequest *) TimerIO);
  1635.    WaitIO((struct IORequest *) TimerIO);
  1636.  
  1637.    Level = LevelOffset;
  1638.    time = oldtime = DEFAULTTICKS - 2*LevelOffset;
  1639.  
  1640.    /* Feld loeschen */
  1641.    for (line=0; line < YSIZE; line++)
  1642.       for (column=1; column<=XSIZE; column++) {
  1643.          field[line][column] = 0;
  1644.          Draw_Box(column, line, 0, FALSE, LEFTFIELD);
  1645.       }
  1646.  
  1647.    ClearNextField(LEFTFIELD);
  1648.  
  1649.    nextptr = RandomObject(LEFTFIELD);
  1650.    objptr = RandomObject(LEFTFIELD);
  1651.    if (nextteil == TRUE)
  1652.       Draw_NextObject(nextptr, FALSE);
  1653.  
  1654.    x = XSIZE/2-1;
  1655.    y = 0;
  1656.    if (InFirstLine(objptr) == TRUE)
  1657.       y = 1;
  1658.  
  1659.    if (TwoPlayer) {
  1660.       time2 = oldtime2 = DEFAULTTICKS - 2*LevelOffset;
  1661.       /* Feld loeschen */
  1662.       for (line=0; line < YSIZE; line++)
  1663.          for (column=1; column<=XSIZE; column++) {
  1664.             field2[line][column] = 0;
  1665.             Draw_Box(column, line, 0, FALSE, RIGHTFIELD);
  1666.          }
  1667.  
  1668.       ClearNextField(RIGHTFIELD);
  1669.  
  1670.       nextptr2 = RandomObject(RIGHTFIELD);
  1671.       objptr2 = RandomObject(RIGHTFIELD);
  1672.       if (nextteil == TRUE)
  1673.          Draw_NextObject(nextptr2, TRUE);
  1674.  
  1675.       x2 = XSIZE/2-1;
  1676.       y2 = 0;
  1677.       if (InFirstLine(objptr2) == TRUE)
  1678.          y2 = 1;
  1679.    }
  1680.  
  1681.    vongameover = FALSE;
  1682.    vonoptions = FALSE;
  1683.  
  1684.    LineCounter = 0;
  1685.  
  1686.    if (Score > Highscore)
  1687.       GT_SetGadgetAttrs(TetrisGadgets[GD_HighscoreGadget], window, NULL, GTNM_Number, (ULONG)Score, TAG_END);
  1688.    else
  1689.       GT_SetGadgetAttrs(TetrisGadgets[GD_HighscoreGadget], window, NULL, GTNM_Number, (ULONG)Highscore, TAG_END);
  1690.  
  1691.    Score = 0;
  1692.  
  1693.    GT_SetGadgetAttrs(TetrisGadgets[GD_ScoreGadget], window, NULL,
  1694.                      GTNM_Number, (ULONG)Score, TAG_END);
  1695.    GT_SetGadgetAttrs(TetrisGadgets[GD_LevelGadget], window, NULL,
  1696.                      GTNM_Number, (ULONG)Level, TAG_END);
  1697.    GT_SetGadgetAttrs(TetrisGadgets[GD_LineGadget], window, NULL,
  1698.                      GTNM_Number, (ULONG)LineCounter, TAG_END);
  1699.    ClearAllMsgPorts();
  1700. }
  1701.  
  1702.  
  1703.  
  1704. void QuitGame(void)
  1705. {
  1706.    if (Score > Highscore) {
  1707.       Highscore = Score;
  1708.       HiscoreList(Name, Level, Score, LineCounter, window->LeftEdge, window->TopEdge, SAVEHISCORE);
  1709.    }
  1710.    closeall();
  1711. }
  1712.  
  1713.  
  1714.  
  1715. BOOL InFirstLine(struct obj *objptr)
  1716. {
  1717.    int column;
  1718.  
  1719.    for (column=0; column<4; column++)
  1720.       if (objptr->objData[0][column] == 1)
  1721.          return(TRUE);
  1722.    return(FALSE);
  1723. }
  1724.  
  1725.  
  1726.  
  1727. int Loadhiscore(void)
  1728. {
  1729.    char   score[10];
  1730.    int    zaehler = 0, hiscore = 0, c;
  1731.    FILE  *fp = NULL;
  1732.    char  *ptr = NULL;
  1733.    char   FName[80];
  1734.  
  1735.    if (getenv("WBTRIS"))
  1736.       strcpy(FName, getenv("WBTRIS"));
  1737.    else
  1738.       strcpy(FName, FILENAME);
  1739.  
  1740.    ptr = &score[0];
  1741.  
  1742.    if ((fp = fopen(FName, "r")) == NULL)
  1743.       return(0);
  1744.    else {
  1745.       while (((c=getc(fp)) != EOF) && (zaehler != 2))
  1746.          if (c == '/') zaehler++;
  1747.  
  1748.       if (c != EOF) {
  1749.          while (c != '/') {
  1750.             *ptr = c;
  1751.             ptr++;
  1752.             c = getc(fp);
  1753.          }
  1754.          *ptr = '\0';
  1755.          hiscore = atoi(score);
  1756.       }
  1757.  
  1758.       fclose(fp);
  1759.       return(hiscore);
  1760.    }
  1761. }
  1762.  
  1763.  
  1764.  
  1765. BOOL AskContinue(void)
  1766. {
  1767.    struct EasyStruct myES = {
  1768.        sizeof(struct EasyStruct),
  1769.        0,
  1770.        "Continue",
  1771.        "Game over\n\nDo you want to play again ?",
  1772.        "YEA|No thanks",
  1773.    };
  1774.    LONG answer;
  1775.  
  1776.    answer = EasyRequest(NULL, &myES, NULL, "(Variable)");
  1777.  
  1778.    if (answer == 1)
  1779.       return(TRUE);
  1780.    else
  1781.       closeall();
  1782. }
  1783.  
  1784.  
  1785.  
  1786. void WaitForActivateWindow(void)
  1787. {
  1788.    BOOL                 Done = FALSE;
  1789.    struct IntuiMessage *imsg = NULL;
  1790.  
  1791.    AbortIO((struct IORequest *) TimerIO);
  1792.    WaitIO((struct IORequest *) TimerIO);
  1793.  
  1794.    HideField();
  1795.  
  1796.    while(!Done)
  1797.    {
  1798.       Wait(1L << window->UserPort->mp_SigBit);
  1799.  
  1800.       while (imsg = (struct IntuiMessage *)GetMsg(window->UserPort)) {
  1801.          switch(imsg->Class) {
  1802.             case IDCMP_ACTIVEWINDOW:
  1803.                Done = TRUE;
  1804.                break;
  1805.  
  1806.             case IDCMP_REFRESHWINDOW:
  1807.                GT_BeginRefresh(window);
  1808.                GT_EndRefresh(window, TRUE);
  1809.                break;
  1810.  
  1811.             case IDCMP_CLOSEWINDOW:
  1812.                QuitGame();
  1813.                break;
  1814.          }
  1815.          ReplyMsg((struct Message *)imsg);
  1816.       }
  1817.    }
  1818.  
  1819.    if (UseLace)
  1820.       EraseImage(rp, &Pausebrush, 190,150);
  1821.    else
  1822.       EraseImage(rp, &Pausebrush, 310,85);
  1823.  
  1824.    ReDrawField(field, LEFTFIELD);
  1825.    ReDrawField(field2, RIGHTFIELD);
  1826. }
  1827.  
  1828.  
  1829.  
  1830. void UpdateStatistic(int objnumber)
  1831. {
  1832.    switch(objnumber) {
  1833.       case 0:
  1834.          obj1++;
  1835.          break;
  1836.       case 1:
  1837.          obj2++;
  1838.          break;
  1839.       case 2:
  1840.          obj3++;
  1841.          break;
  1842.       case 3:
  1843.          obj4++;
  1844.          break;
  1845.       case 4:
  1846.          obj5++;
  1847.          break;
  1848.       case 5:
  1849.          obj6++;
  1850.          break;
  1851.       case 6:
  1852.          obj7++;
  1853.          break;
  1854.    }
  1855. }
  1856.  
  1857.  
  1858.  
  1859. /*
  1860. ** Put rows onto the opponent's fieldbottom (only for 2-player-mode)
  1861. */
  1862. void PutRows(int field[YSIZE+1][XSIZE+2], BOOL RightOrLeft, int NumberOfRows)
  1863. {
  1864.    int i, j;
  1865.    short line, column;
  1866.    BOOL FoundNull = FALSE;
  1867.    int NewRow[XSIZE+2];
  1868.    short Farbe;
  1869.  
  1870.    /* build new row */
  1871.    Farbe = 1 + rand() % 7;
  1872.    for (i = 0; i < XSIZE+2; i++)
  1873.       NewRow[i] = Farbe;
  1874.    NewRow[0]       = -1;
  1875.    NewRow[XSIZE+1] = -1;
  1876.    NewRow[1 + rand() % XSIZE] = 0;
  1877.  
  1878.    /* Put rows onto the opponent's field */
  1879.    for (j = 0; j < NumberOfRows; j++) {
  1880.  
  1881.       /* move field one row up */
  1882.       for (line = 0; line < YSIZE-1; line++)
  1883.          for (column = 1; column < XSIZE + 1; column++)
  1884.             field[line][column] = field[line+1][column];
  1885.  
  1886.       /* insert new row */
  1887.       for (i=0; i<XSIZE+2; i++)
  1888.          field[YSIZE-1][i] = NewRow[i];
  1889.  
  1890.       /* Abfrage auf Spielende */
  1891.       /*GameOver(field, lockname);*/
  1892.  
  1893.       /* Redraw the field */
  1894.       ReDrawField(field, RightOrLeft);
  1895.       if (RightOrLeft == RIGHTFIELD)
  1896.          Draw_Object(x2, y2, objptr2, TRUE, RIGHTFIELD);
  1897.       else
  1898.          Draw_Object(x, y, objptr, TRUE, LEFTFIELD);
  1899.    }
  1900. }
  1901.  
  1902.  
  1903.  
  1904. /*
  1905. ** executes a refresh of the playfield(s)
  1906. */
  1907. void ReDrawField(int field[YSIZE+1][XSIZE+2], BOOL RightOrLeft)
  1908. {
  1909.    short line, column;
  1910.  
  1911.    for (line=1; line < YSIZE; line++) {
  1912.       for (column=1; column < XSIZE+1; column++)
  1913.          switch(field[line][column]) {
  1914.             case 0:
  1915.                Draw_Box(column, line, 0, FALSE, RightOrLeft);
  1916.                break;
  1917.             case 1:
  1918.                Draw_Box(column, line, 1, TRUE, RightOrLeft);
  1919.                break;
  1920.             case 2:
  1921.                Draw_Box(column, line, 2, TRUE, RightOrLeft);
  1922.                break;
  1923.             case 3:
  1924.                Draw_Box(column, line, 3, TRUE, RightOrLeft);
  1925.                break;
  1926.             case 4:
  1927.                Draw_Box(column, line, 4, TRUE, RightOrLeft);
  1928.                break;
  1929.             case 5:
  1930.                Draw_Box(column, line, 5, TRUE, RightOrLeft);
  1931.                break;
  1932.             case 6:
  1933.                Draw_Box(column, line, 6, TRUE, RightOrLeft);
  1934.                break;
  1935.             case 7:
  1936.                Draw_Box(column, line, 7, TRUE, RightOrLeft);
  1937.                break;
  1938.          }
  1939.    }
  1940. }
  1941.  
  1942.  
  1943.  
  1944. void HideField(void)
  1945. {
  1946.    SetAPen(rp, 0);
  1947.    RectFill(rp, MAINXOFFSET+16, YOffSet-1, MAINXOFFSET+16 + (XSIZE+1)*boxxsize-15, YOffSet + YSIZE*boxysize+1);
  1948.  
  1949.    if (UseLace)
  1950.       DrawImage(rp, &Pausebrush, 190, 150);
  1951.    else
  1952.       DrawImage(rp, &Pausebrush, 310, 85);
  1953.  
  1954.    if (TwoPlayer) {
  1955.       RectFill(rp, MAINXOFFSET+16  + XSIZE*boxxsize + FieldsSpace, YOffSet-1, MAINXOFFSET+16 + (XSIZE+1)*boxxsize-15 + XSIZE*boxxsize + FieldsSpace, YOffSet + YSIZE*boxysize+1);
  1956.  
  1957.       if (UseLace)
  1958.          DrawImage(rp, &Pausebrush, 190 + XSIZE*boxxsize + FieldsSpace, 150);
  1959.       else
  1960.          DrawImage(rp, &Pausebrush, 310 + XSIZE*boxxsize + FieldsSpace, 85);
  1961.    }
  1962. }
  1963.  
  1964.  
  1965.  
  1966. void ClearAllMsgPorts(void)
  1967. {
  1968.    struct I0ExtSer     *reply = NULL;
  1969.    struct IntuiMessage *imsg = NULL;
  1970.  
  1971.    while(reply = (struct I0ExtSer *)GetMsg(TimerMP))
  1972.    {}
  1973.    if (TwoPlayer) {
  1974.       while(reply = (struct I0ExtSer *)GetMsg(TimerMP2))
  1975.       {}
  1976.    }
  1977.    while (imsg = (struct IntuiMessage *)GetMsg(window->UserPort))
  1978.       ReplyMsg((struct Message *)imsg);
  1979. }
  1980.